# -*- coding: utf-8 -*-
from __future__ import print_function

import sys
import os
import copy

reload(sys)
sys.setdefaultencoding("utf-8")

"""
114. 二叉树展开为链表
给你二叉树的根结点 root ，请你将它展开为一个单链表：

展开后的单链表应该同样使用 TreeNode ，其中 right 子指针指向链表中下一个结点，而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
 

示例 1：


输入：root = [1,2,5,3,4,null,6]
输出：[1,null,2,null,3,null,4,null,5,null,6]
示例 2：

输入：root = []
输出：[]
示例 3：

输入：root = [0]
输出：[0]
 

提示：

树中结点数在范围 [0, 2000] 内
-100 <= Node.val <= 100
 

进阶：你可以使用原地算法（O(1) 额外空间）展开这棵树吗？

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def flatten(self, root):
        """
        :type root: TreeNode
        :rtype: None Do not return anything, modify root in-place instead.
        """
        # 前序遍历迭代
        # 先前序遍历，在展平
        # preorderList = []
        # stack = []
        # node = root
        # while node or stack:
        #     while node:
        #         # 前序遍历 根左右
        #         preorderList.append(node)
        #         stack.append(node)
        #         node = node.left
        #     node = stack.pop()
        #     node = node.right
        # size = len(preorderList)
        # for i in range(1, size):
        #     pre, cur = preorderList[i-1], preorderList[i]
        #     pre.left = None
        #     pre.right = cur

        ## 前序遍历递归
        # preorderList = []
        #
        # def preorderTraversal(root):
        #     if root:
        #         preorderList.append(root)
        #         preorderTraversal(root.left)
        #         preorderTraversal(root.right)
        #
        # preorderTraversal(root)
        # size = len(preorderList)
        # for i in range(1, size):
        #     prev, curr = preorderList[i - 1], preorderList[i]
        #     prev.left = None
        #     prev.right = curr

        # 不需要额外空间的
        # 就是如何把左右子树挂在一起，而且不影响，前序遍历的结果；
        curr = root
        while curr:
            if curr.left:
                predecessor = nxt = curr.left
                while predecessor.right:
                    predecessor = predecessor.right
                predecessor.right = curr.right
                curr.left = None
                curr.right = nxt
            curr = curr.right